﻿using Abp.Application.Services;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Microsoft.AspNetCore.Http;
using MySqlX.XDevAPI.Common;
using NPOI.SS.Formula.Functions;
using Senparc.NeuChar.Entities.App;
using SportsPlatform.Base;
using SportsPlatform.Consts;
using SportsPlatform.Dto.SportBusiness.Competition;
using SportsPlatform.Dto.SportBusiness.RegistrationInfo;
using SportsPlatform.Enums;
using SportsPlatform.Global;
using SportsPlatform.Helpers;
using SportsPlatform.Model.PermissionManagement;
using SportsPlatform.Model.SportBusiness;
using SportsPlatform.Query.SportBusiness.Information;
using SportsPlatform.Query.SportBusiness.RegistrationInfo;
using SportsPlatform.Query.WeiXinPay;
using SportsPlatform.SportBusiness.ISportBusiness;
using SportsPlatform.SqlExecuter;
using SportsPlatform.WeiXinPay.WeiXinPay;
using SqlSugar.Extensions;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;

namespace SportsPlatform.SportBusiness.SportBusiness
{
    /// <summary>
    /// 报名管理
    /// </summary>
    [RemoteService(false)]  //隐藏自动生成的WebApi
    public class RegistrationInfoService : SportsPlatformAppServiceBase, IRegistrationInfoService
    {
        private readonly IRepository<RegistrationInfo, Guid> _repository;
        private readonly ISqlExecuterRepository _sqlExecuterRepository;
        private readonly IRepository<Employee, Guid> _employeeRepository;
        private readonly IRepository<UserInfo, Guid> _userInfoRepository;
        private readonly IRepository<PaymentOrderInfo, Guid> _payOrderRepository;
        private readonly IRepository<CompetitionProject, Guid> _comProjectRepository;
        private readonly IRepository<PaymentOrderOperationInfo, Guid> _oderoperRepository;
        private readonly IRepository<Competition, Guid> _competitionRepository;
        private readonly IRepository<CompeteTeam, Guid> _comTeamRepository;
        private readonly IRepository<CompanyInfo, Guid> _companyRepository;
        private readonly IHttpContextAccessor _context;

        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="sqlExecuterRepository"></param>
        /// <param name="employeeRepository"></param>
        /// <param name="userInfoRepository"></param>
        /// <param name="payOrderRepository"></param>
        /// <param name="companyRepository"></param>
        /// <param name="comProjectRepository"></param>
        /// <param name="oderoperRepository"></param>
        /// <param name="comTeamRepository"></param>
        /// <param name="competition"></param>
        /// <param name="context"></param>
        public RegistrationInfoService(IRepository<RegistrationInfo, Guid> repository
            , ISqlExecuterRepository sqlExecuterRepository,
            IRepository<Employee, Guid> employeeRepository,
            IRepository<UserInfo, Guid> userInfoRepository,
            IRepository<PaymentOrderInfo, Guid> payOrderRepository,
            IRepository<CompanyInfo, Guid> companyRepository,
            IRepository<CompetitionProject, Guid> comProjectRepository,
            IRepository<PaymentOrderOperationInfo, Guid> oderoperRepository,
            IRepository<CompeteTeam, Guid> comTeamRepository,
            IRepository<Competition, Guid> competition, IHttpContextAccessor context) : base(context)
        {
            _repository = repository;
            _sqlExecuterRepository = sqlExecuterRepository;
            _employeeRepository = employeeRepository;
            _userInfoRepository = userInfoRepository;
            _comTeamRepository = comTeamRepository;
            _payOrderRepository = payOrderRepository;
            _companyRepository = companyRepository;
            _comProjectRepository = comProjectRepository;
            _oderoperRepository = oderoperRepository;
            _competitionRepository = competition;
            _context = context;
        }

        /// <summary>
        /// 列表查询
        /// </summary>
        /// <param name="Query"></param>
        /// <returns></returns>
        public async Task<PagePagingDto<RegistrationInfoListDto>> GetRegistrationInfoList(GetRegistrationInfoListQuery Query)
        {
            PagePagingDto<RegistrationInfoListDto> result = new PagePagingDto<RegistrationInfoListDto>();
            try
            {
                var token = UldAdminSessionContext.GetCurrentUserInfo(_context);
                var oders = await _oderoperRepository.GetAllListAsync(o => o.IsDeleted == false);
                var where = " where 1=1";
                var w = " where 1=1";
                if (Query.Competition != null && !(Query.Competition == Guid.Empty))
                {
                    w += $" and c.Id = '{Query.Competition}'";
                }
                if (Query.Project != null && !(Query.Project == Guid.Empty))
                {
                    w += $" and cp.Id = '{Query.Project}'";
                }
                if (token.CompanyId != null)
                {
                    w += $" and c.Merchants = '{token.CompanyId}'";
                }
                if (Query.RegistrationStatus != null && Query.RegistrationStatus > 0)
                {
                    where += $" and com.RegistrationStatus = '{Query.RegistrationStatus}'";
                }
                if (Query.StartTime.HasValue)
                {
                    where += $" and com.CompetitionStartTime >= '{Query.StartTime}'";
                }
                if (Query.EndTime.HasValue)
                {
                    where += $" and com.CompetitionEndTime <= '{Query.EndTime}'";
                }
                if (Query.StartRegistrationSubmissionTime.HasValue)
                {
                    where += $" and com.RegistrationSubmissionTime >= '{Query.StartRegistrationSubmissionTime}'";
                }
                if (Query.EndRegistrationSubmissionTime.HasValue)
                {
                    where += $" and com.RegistrationSubmissionTime <= '{Query.EndRegistrationSubmissionTime}'";
                }
                if (!string.IsNullOrWhiteSpace(Query.KeyWord))
                {
                    where += $" and com.CompetitionName like '%{Query.KeyWord}%' or com.CompetitionProjectName like '%{Query.KeyWord}%' or com.CompeteName like '%{Query.KeyWord}%' ";
                }
                string sql = string.Format("select * from (select " +
                    "rif.Id,rif.CompeteName,rif.CompeteTel,rif.CompeteIdNo,rif.SensorNumber,rif.CompeteTeamName," +
                    "c.[Name] as CompetitionName, cp.[Name] as CompetitionProjectName,cp.GameBeginTime as CompetitionStartTime,cp.GameEndTime as CompetitionEndTime," +
                    "cp.DetailsAddress as CompetitionAddress,rif.RegistrationSubmissionTime,rif.EmployeeId,'' as EmployeeName,'' as EmployeeTelephone," +
                    "com.CompanyName AS Merchant,o.OrderNumber as PaymentOrderNo,rif.RegistrationSource,rif.RegistrationStatus,rif.ReviewComments," +
                    "rif.AuditTime,rif.ReviewedUserId as ReviewedUserId,'' as ReviewedUser " +
                    "from T_B_RegistrationInfo rif " +
                    "left join T_B_Competition c on rif.CompetitionID = c.Id " +
                    "left join T_B_CompetitionProject cp on rif.CompetitionProjectID = cp.Id " +
                    "left join T_B_PaymentOrderInfo o on rif.PaymentOrderId=o.Id and o.OrderStatus>0 and o.PaymentStatus>0 " +
                    "left join PM_CompanyInfo com on c.Id = c.Merchants " + w + " ) com " + where);
                var list = (await _sqlExecuterRepository.QueryAsync<RegistrationInfoListDto>(sql)).ToList();
                if (list.Count() > 0)
                {
                    var regs = new List<RegistrationInfoListDto>();

                    var emplist = await _employeeRepository.GetAllListAsync();
                    var userlist = await _userInfoRepository.GetAllListAsync();
                    var reglist = await _repository.GetAllListAsync();
                    var comlist=await _competitionRepository.GetAllListAsync();
                    var companylist=await _companyRepository.GetAllListAsync();
                    foreach (var item in list)
                    {
                        var reginfo = reglist.FirstOrDefault(info => info.Id == item.Id);
                        item.CompeteTel = string.IsNullOrEmpty(item?.CompeteTel ?? "") ? "" : (item.CompeteTel.Substring(0, 3) + "****" + item.CompeteTel.Substring(item.CompeteTel.Length - 4, 4));
                        item.CompeteIdNo = string.IsNullOrEmpty(item?.CompeteIdNo ?? "") ? "" : (item.CompeteIdNo.Substring(0, 6) + "********" + item.CompeteIdNo.Substring(item.CompeteIdNo.Length - 4, 4));
                        if (item.EmployeeId == Guid.Empty || item.EmployeeId == null)
                        {
                            var user = userlist.FirstOrDefault(info => info.Id == reginfo?.CreateUserId);
                            item.EmployeeName = user?.UserName ?? "";
                            item.EmployeeTelephone = string.IsNullOrEmpty(user?.UserTel ?? "") ? "" : (user.UserTel.Substring(0, 3) + "****" + user.UserTel.Substring(user.UserTel.Length - 4, 4));
                        }
                        else
                        {
                            var emp = emplist.Where(a => a.Id == (Guid)item.EmployeeId).FirstOrDefault();
                            var user = userlist.Where(a => a.Id == (Guid)item.EmployeeId).FirstOrDefault();
                            item.EmployeeName = emp?.RealName ?? user?.UserName??"";
                            item.EmployeeTelephone = emp?.Phone ?? user?.UserTel ?? "";
                            item.EmployeeTelephone = String.IsNullOrEmpty(item.EmployeeTelephone) ? "" : (item.EmployeeTelephone.Substring(0, 3) + "****" + item.EmployeeTelephone.Substring(item.EmployeeTelephone.Length - 4, 4));
                        }
                        if (item.ReviewedUserId != Guid.Empty && item.ReviewedUserId != null)
                        {
                            var user = userlist.Where(a => a.Id == (Guid)item.ReviewedUserId).FirstOrDefault();
                            item.ReviewedUser = user?.UserName ?? "";
                        }
                        else
                        {
                            if (!item.RegistrationStatus.Equals(((int)RegistrationStatusEnum.待审核).ToString()))
                            {
                                var createuser = userlist.FirstOrDefault(info => info.Id == reginfo?.CreateUserId);
                                var updateuser = userlist.FirstOrDefault(info => info.Id == reginfo?.UpdateUserId);
                                item.ReviewedUser = updateuser?.UserName ?? createuser?.UserName ?? "";
                                item.AuditTime = reginfo?.AuditTime ?? reginfo?.UpdateTime ?? reginfo?.CreateTime;
                            }
                        }
                        item.Merchant = companylist.FirstOrDefault(info => info.Id == comlist.FirstOrDefault(c => c.Id == reginfo.CompetitionId)?.Merchants)?.CompanyName;
                        item.RegistrationSource = Enum.GetName(typeof(RegistrationSourceEnum), Convert.ToInt32(item.RegistrationSource));//报名来源
                        item.RegistrationStatus = Enum.GetName(typeof(RegistrationStatusEnum), Convert.ToInt32(item.RegistrationStatus));//报名状态
                        regs.Add(item);
                    }
                    result.Data = regs.OrderByDescending(r => r.RegistrationSubmissionTime).Skip((Query.PageIndex - 1) * Query.PageSize).Take(Query.PageSize);
                    result.TotalCount = regs.Count();
                    result.Code = HttpResultCode.Success;
                    result.IsSuccess = true;
                    result.Message = "查询成功！";
                    result.TotalPage = (int)Math.Round((list.Count() / Query.PageSize).ObjToDecimal(), MidpointRounding.ToPositiveInfinity);
                }
                else
                {
                    result.TotalCount = 0;
                    result.Code = HttpResultCode.NotData;
                    result.IsSuccess = false;
                    result.Data = null;
                    result.Message = "未查询到数据";
                    result.TotalPage = 0;
                }
            }
            catch (Exception ex)
            {
                result.TotalCount = 0;
                result.Code = HttpResultCode.Error;
                result.IsSuccess = false;
                result.Data = null;
                result.Message = ex.Message;
            }
            return result;
        }

        /// <summary>
        /// 添加报名
        /// </summary>
        /// <param name="Query"></param>
        /// <returns></returns>
        public async Task<BaseResultDto> AddRegistrationInfo(AddRegistrationInfoQuery Query)
        {
            var result = new BaseResultDto();
            try
            {
                var infoID = Guid.Empty;
                //通过token获取当前PC端登陆用户信息
                var token = UldAdminSessionContext.GetCurrentUserInfo(_context);

                //查询所有未删除，状态为报名成功的报名信息
                var infos = await _repository.GetAllListAsync(r => r.IsDeleted == false && r.RegistrationStatus == (int)RegistrationStatusEnum.报名成功);

                //获取跟传入的赛事ID相同的赛事，和状态为正在报名的赛事
                var com = await _competitionRepository.FirstOrDefaultAsync(c => c.Id == Query.CompetitionId && (c.State == (int)CompetitionStateEnum.正在报名 || c.State == (int)CompetitionStateEnum.报名结束待比赛 || c.State == (int)CompetitionStateEnum.正在比赛));

                //判断赛事是否存在
                if (com.IsNullAndEmpty())
                {
                    result.Code = HttpResultCode.NotData;
                    result.IsSuccess = false;
                    result.Message = "传入的赛事不存在,请重新选择赛事";
                    return result;
                }

                //查询赛事项目未删除的且状态大于等于2  状态：（0：关闭；1：待报名；2：正在报名；3：待分组；4：待签到；5：正在比赛；6：比赛结束）
                var comproject = await _comProjectRepository.FirstOrDefaultAsync(cp => cp.IsDeleted == false && cp.State >= (int)CompetitionProjectStateEnum.正在报名 && cp.Id == Query.CompetitionProjectId && cp.State < (int)CompetitionProjectStateEnum.比赛结束);

                //判断赛事项目是否存在
                if (comproject.IsNullAndEmpty())
                {
                    result.Code = HttpResultCode.NotData;
                    result.IsSuccess = false;
                    result.Message = "传入的赛事项目不存在,请重新选择赛事项目";
                    return result;
                }
                //查询未删除的用户列表
                var ems = await _employeeRepository.GetAllListAsync(em => em.IsDeleted == false);

                //查询所有赛事项目团队信息
                var comteamlist = await _comTeamRepository.GetAllListAsync(info => info.IsDeleted == false && info.CompetitionProjectId == Query.CompetitionProjectId);

                var num = 1;

                //循环传入的参赛用户信息
                Query.EmployeeInfos.ForEach(async e =>
                {
                    var reg = new RegistrationInfo
                    {
                        CreateTime = DateTime.Now,
                        IsDeleted = false,
                        CreateUserId = token.Id,
                        RegistrationSubmissionTime = DateTime.Now,
                        CompetitionId = com.Id,
                        CompetitionProjectId = comproject.Id,
                        RegistrationSource = (int)RegistrationSourceEnum.线下报名,
                        SensorNumber = e.SensorNumber,
                        EmployeeId = Guid.Empty,
                        ReviewComments = "",
                        CompeteTeamName = e.CompeteTeamName,
                        CompeteIdNo = e.CompeteIdNo,
                        CompeteName = e.CompeteName,
                        CompeteTel = e.CompeteTel,
                        RegistrationStatus = 1
                    };
                    //判断当前赛事收费类型是否等于赛事收费 等于 1:按照项目收费； 2:按照赛事收费
                    if (com.ChargeType == 2)
                    {
                        reg.Money = com.Money.Value;
                    }
                    else
                    {
                        reg.Money = comproject.CostMoney.Value;
                    }

                    //查询用户列表中与传入身份证号相同的用户
                    var em = ems.FirstOrDefault(es => es.IDNumber == e.CompeteIdNo);

                    //订单所需用户ID
                    var orderEmloyeeID = Guid.Empty;

                    #region 判断是否存在相同身份证号的用户 true：存在就只赋值报名信息；false：不存在创建新用户
                    if (!em.IsNullAndEmpty())
                    {
                        reg.CompeteName = e.CompeteName;
                        reg.CompeteTeamName = e.CompeteTeamName;
                        reg.CompeteTel = e.CompeteTel;
                        reg.CompeteIdNo = e.CompeteIdNo;
                        reg.EmployeeId = em.Id;
                        orderEmloyeeID = em.Id;
                    }
                    else //用户不存在，就新增用户
                    {
                        var emloyee = new Employee
                        {
                            RealName = e.CompeteName,
                            CreateTime = DateTime.Now,
                            CreateUserId = token.Id,
                            IDNumber = e.CompeteIdNo,
                            OpenId = "",
                            Phone = e.CompeteTel,
                            RegisterTime = DateTime.Now,
                            Sensor = e.SensorNumber,
                            HeadPortrait = "",
                            NickName = "",
                            Sex = 1,
                        };

                        //插入新用户信息
                        var emplyeeId = await _employeeRepository.InsertAndGetIdAsync(emloyee);
                        orderEmloyeeID = emplyeeId;
                    }
                    #endregion

                    #region 判断参赛团队是否存在
                    if (comproject.GameType == (int)CompetitionProjectTypeEnum.团队接力赛)
                    {
                        if (!e.CompeteTeamName.IsNullAndEmpty())
                        {
                            //comteamlist 已经通过赛事项目Id筛选了，这里不用再次用赛事项目筛选
                            var comteaminfo = comteamlist.FirstOrDefault(info => info.Name == e.CompeteTeamName);
                            //为空就新建
                            if (comteaminfo == null)
                            {
                                Guid id = Guid.NewGuid();
                                //这里new是为了防止后面修改遗忘这里引用
                                var comteam = new CompeteTeam()
                                {
                                    Id = id,
                                    Name = e.CompeteTeamName,
                                    CompetitionProjectId = Query.CompetitionProjectId,
                                    IsDeleted = false
                                };
                                //efcore事后才执行，会导致之前插入了查询不到
                                string sql = $"insert into T_B_CompeteTeam(Id,Name,CompetitionProjectId,IsDeleted) values('{comteam.Id}','{comteam.Name}','{comteam.CompetitionProjectId}',0)";
                                _sqlExecuterRepository.Execute(sql, null);
                                reg.CompeteTeamId = id;
                                //插入之后重新获取,这里不能用异步，异步会导致程序运行快，数据库未查询到上条插入的数据，导致又会创建一条数据
                                comteamlist =  _comTeamRepository.GetAllList(info => info.IsDeleted == false && info.CompetitionProjectId == Query.CompetitionProjectId);
                            }
                            else
                            {
                                reg.CompeteTeamId = comteaminfo.Id;
                            }
                        }
                    }
                    #endregion

                    //生成订单信息
                    var orderID = await _payOrderRepository.InsertAndGetIdAsync(new PaymentOrderInfo
                    {
                        CompanyID = token.CompanyId.IsNullAndEmpty() ? Guid.Empty : (Guid)token.CompanyId,
                        CompetitionID = com.Id,
                        ContactTel = e.CompeteTel,
                        CreateTime = DateTime.Now,
                        EmployeeID = orderEmloyeeID,
                        CreateUserId = token.Id,
                        OrderSource = (int)SourceEnum.web端,
                        PaymentStatus = (int)PaymentStatusEnum.支付成功,
                        PaymentMethod = (int)PaymentMethodEnum.线下支付,
                        PaymentTime = DateTime.Now,
                        OrderCloseNotes = "",
                        OrderNotes = "",
                        OrderNumber = Guid.NewGuid().ToString(),
                        OrderOddNumbers = "",
                        PaymentFee = comproject.CostMoney.Value,
                        SubmitTime = DateTime.Now,
                        OrderStatus = (int)OrderStatusEnum.已付款,
                    });

                    reg.PaymentOrderId = orderID;
                    if (comproject.GameType == (int)CompetitionProjectTypeEnum.个人赛)
                    {
                        //获取当前项目的报名数量
                        var registrCount = infos.Where(a => a.CompetitionProjectId == Query.CompetitionProjectId).ToList().Count();
                        reg.SerialNum = registrCount + num;
                        num++;
                    }
                    if (Query.RequestSource == 1)
                    {
                        reg.RegistrationStatus = 2;
                    }
                    infoID = await _repository.InsertAndGetIdAsync(reg);
                });

                if (!infoID.IsNullAndEmpty())
                {
                    result.Code = 200;
                    result.IsSuccess = true;
                    result.Message = "添加报名成功";
                    return result;
                }
                else
                {
                    result.Code = HttpResultCode.SqlError;
                    result.IsSuccess = false;
                    result.Message = "添加报名失败";
                    return result;
                }
            }
            catch (Exception ex)
            {
                return new BaseResultDto()
                {
                    IsSuccess = false,
                    Code = (int)HttpResultCode.Error,
                    Message = ex.Message
                };
            }

        }

        /// <summary>
        /// 审批数据查询
        /// </summary>
        /// <param name="Query"></param>
        /// <returns></returns>
        public async Task<ResultDto<ApprovalGetRegistrationInfoDetailsDto>> ApprovalGetRegistrationInfoDetails(RegistrationInfoDetailsQuery Query)
        {
            ResultDto<ApprovalGetRegistrationInfoDetailsDto> result = new ResultDto<ApprovalGetRegistrationInfoDetailsDto>();
            try
            {
                //string sql = string.Format("select * from (select " +
                //        "rif.Id,rif.CompeteName,rif.CompeteTel,t.TeamName,rif.CompeteIdNo,rif.SensorNumber,rif.CompeteTeamName,cp.GameDate,'' as ProjectDateTImeStr," +
                //        "c.[Name] as CompetitionName, cp.[Name] as CompetitionProjectName,cp.MaxEmployeeNum, cp.GameBeginTime as CompetitionStartTime,cp.GameEndTime as CompetitionEndTime," +
                //        "cp.DetailsAddress as CompetitionAddress,rif.RegistrationSubmissionTime,EmployeeId as EmployeeName,EmployeeId as EmployeeTelephone," +
                //        "c.Merchants as Merchant,rif.PaymentOrderId as PaymentOrderNo,rif.RegistrationSource,rif.RegistrationStatus,rif.ReviewComments," +
                //        "rif.AuditTime,rif.ReviewedUserId as ReviewedUser,rif.SerialNum as RegistrationNo" +
                //        "from T_B_RegistrationInfo rif " +
                //        "left join T_B_Team t on rif.TeamID = t.Id " +
                //        "left join T_B_Competition c on rif.CompetitionID = c.Id " +
                //        $"left join T_B_CompetitionProject cp on rif.CompetitionProjectID = cp.Id) com where com.Id ='{Query.Id}'");
                //var fir = await _sqlExecuterRepository.QueryFirstAsync<ApprovalGetRegistrationInfoDetailsDto>(sql);

                //查询报名信息
                var reg = await _repository.GetAsync(Query.Id);

                //查询赛事
                var cm = await _competitionRepository.GetAsync(reg.CompetitionId);

                //查询项目信息
                var cmp = await _comProjectRepository.GetAsync(reg.CompetitionProjectId);

                var rSum = await _repository.GetAllListAsync(r => r.CompetitionId == cm.Id && r.CompetitionProjectId == cmp.Id);




                result.Code = HttpResultCode.Success;
                result.IsSuccess = true;
                result.Data = new ApprovalGetRegistrationInfoDetailsDto
                {
                    Id = reg.Id,
                    RegistrationNo = reg.SerialNum,
                    RemainingSeats = cmp.MaxEmployeeNum - rSum.Count(),
                    GameDate = cmp.GameBeginTime.Date,
                    CompeteIdNo = reg.CompeteIdNo,
                    CompeteName = reg.CompeteName,
                    CompetitionEndTime = cmp.GameEndTime,
                    CompetitionName = cm.Name,
                    CompetitionProjectName = cmp.Name,
                    CompetitionStartTime = cmp.GameBeginTime,
                    MaxEmployeeNum = cmp.MaxEmployeeNum,
                    SensorsMaxNum = cmp.SensorsMaxNum.Value,
                };
                result.Message = "查询成功";
            }
            catch (Exception ex)
            {
                result.Code = HttpResultCode.Error;
                result.IsSuccess = false;
                result.Data = null;
                result.Message = ex.Message;
            }
            return result;
        }

        /// <summary>
        /// 审批数据
        /// </summary>
        /// <param name="Query"></param>
        /// <returns></returns>
        public async Task<BaseResultDto> ApprovalRegistrationInfo(ApprovalRegistrationInfo Query)
        {
            try
            {
                var token = UldAdminSessionContext.GetCurrentUserInfo(_context);

                //先判断Token用户，免得退款之后在验证失败
                var userinfo = await _userInfoRepository.FirstOrDefaultAsync(info => info.Id == token.Id);
                if (userinfo == null)
                {
                    return new BaseResultDto()
                    {
                        IsSuccess = false,
                        Code = HttpResultCode.Fail,
                        Message = "ToKen传入UID有误！"
                    };
                }
                var item = await _repository.FirstOrDefaultAsync(Query.Id);
                if (item != null)
                {
                    #region 审核不通过则退款
                    //审核不通过则退款
                    if (Query.RegistrationStatus != 1)
                    {
                        //是否退钱
                        bool isrefund = false;
                        var projectinfo = await _comProjectRepository.FirstOrDefaultAsync(info => info.Id == item.CompetitionProjectId);
                        if (projectinfo == null)
                        {
                            return new BaseResultDto()
                            {
                                IsSuccess = false,
                                Code = HttpResultCode.Fail,
                                Message = "审核项目不存在！"
                            };
                        }
                        if (projectinfo.GameType == (int)CompetitionProjectTypeEnum.个人赛)
                        {
                            isrefund = true;
                        }
                        else
                        {
                            //如果是团体赛，全被审核失败，最后一个的时候才退款，否则不退款
                            var reginfolist = await _repository.GetAllListAsync(info => info.CompetitionId == item.CompetitionId && info.CompetitionProjectId == item.CompetitionProjectId && info.CompeteTeamName == item.CompeteTeamName && info.PaymentOrderId == item.PaymentOrderId && info.IsDeleted == false);
                            if (reginfolist != null && reginfolist.Count > 0)
                            {
                                isrefund = true;
                                foreach (var reg in reginfolist)
                                {
                                    //多条表示团体赛，判断除开自己是否还存在待审核和报名成功，有一个待审核或报名成功，就不退钱
                                    if (reg.Id != item.Id)
                                    {
                                        if (reg.RegistrationStatus == (int)RegistrationStatusEnum.待审核 || reg.RegistrationStatus == (int)RegistrationStatusEnum.报名成功)
                                        {
                                            isrefund = false;
                                            break;
                                        }
                                    }
                                }

                            }
                            //如果退钱则说明是最后一个不通过，则删除参赛团队信息，避免其他人不能复用该名称
                            if (isrefund)
                            {
                                var comteaminfo = await _comTeamRepository.FirstOrDefaultAsync(info => info.Id == item.CompeteTeamId);
                                if (comteaminfo != null)
                                {
                                    comteaminfo.IsDeleted = true;
                                    await _comTeamRepository.UpdateAsync(comteaminfo);
                                }
                            }
                        }
                        if (isrefund)
                        {
                            //查询订单数据
                            var payorder = await _payOrderRepository.FirstOrDefaultAsync(info => info.Id == item.PaymentOrderId);
                            if (payorder != null && payorder.PaymentFee > 0)
                            {
                                //退款
                                RefundQuery refundquery = new RefundQuery();
                                refundquery.OutTradeNo = payorder.OrderNumber;
                                refundquery.Amount = item.Money;
                                refundquery.Reason = projectinfo.Name + "报名审核未通过退款";

                                WeiXinTenPayV3Service weixinpay = new WeiXinTenPayV3Service(_context);
                                var refundret = await weixinpay.Refund(refundquery);
                                if (refundret.IsSuccess == true)
                                {
                                    //订单操作表数据录入 
                                    PaymentOrderOperationInfo operinfo = new PaymentOrderOperationInfo();
                                    operinfo.CreateTime = DateTime.Now;
                                    operinfo.CreateUserId = userinfo.Id;
                                    operinfo.OperationName = userinfo.UserName;
                                    operinfo.OperationTime = DateTime.Now;
                                    operinfo.OperationDetails = projectinfo.Name + "报名审核未通过退款";
                                    operinfo.PaymentOrderID = payorder.Id;
                                    operinfo.RegistrationID = item.Id;
                                    operinfo.OrderState = (int)OrderStatusEnum.已退款;
                                    operinfo.PaymentState = (int)PaymentStatusEnum.已退款;
                                    await _oderoperRepository.InsertAsync(operinfo);
                                }
                                else
                                {
                                    return new BaseResultDto()
                                    {
                                        IsSuccess = false,
                                        Code = HttpResultCode.Fail,
                                        Message = "退款失败：" + refundret.Message
                                    };
                                }
                                //判断订单钱是否全部退完。退完更改状态
                                decimal operfee = 0;
                                operfee += item.Money;//加上当前退款金额是因为ABP过后才会插入表数据
                                var orderoperlist = await _oderoperRepository.GetAllListAsync(info => info.PaymentOrderID == payorder.Id && info.PaymentState == (int)PaymentStatusEnum.已退款);
                                if (orderoperlist != null && orderoperlist.Count > 0)
                                {
                                    foreach (var orderoperitem in orderoperlist)
                                    {
                                        operfee += (await _repository.FirstOrDefaultAsync(info => info.Id == orderoperitem.RegistrationID)).Money;
                                    }
                                }
                                if (payorder.PaymentFee <= operfee)
                                {
                                    payorder.PaymentStatus = (int)PaymentStatusEnum.已退款;
                                    payorder.OrderStatus = (int)OrderStatusEnum.已退款;
                                    payorder.UpdateUserId = userinfo.Id;
                                    payorder.UpdateTime = DateTime.Now;
                                    await _payOrderRepository.UpdateAsync(payorder);
                                }
                            }
                            //订单金额为0 更改订单状态
                            if (payorder != null && payorder.PaymentFee == 0)
                            {
                                payorder.PaymentStatus = (int)PaymentStatusEnum.已退款;
                                payorder.OrderStatus = (int)OrderStatusEnum.已退款;
                                payorder.UpdateUserId = userinfo.Id;
                                payorder.UpdateTime = DateTime.Now;
                                await _payOrderRepository.UpdateAsync(payorder);
                            }
                        }
                    }
                    #endregion

                    //更改报名状态
                    if (Query.RegistrationStatus == 1)
                    {
                        item.RegistrationStatus = (int)RegistrationStatusEnum.报名成功;
                    }
                    else
                    {
                        item.RegistrationStatus = (int)RegistrationStatusEnum.报名失败;
                    }
                    item.ReviewComments = Query.ReviewComments;
                    item.AuditTime = DateTime.Now;
                    item.ReviewedUserId = userinfo.Id;
                    item.UpdateTime = DateTime.Now;
                    item.UpdateUserId = userinfo.Id;
                    await _repository.UpdateAsync(item);
                    return new BaseResultDto()
                    {
                        IsSuccess = true,
                        Code = HttpResultCode.Success,
                        Message = "操作成功"
                    };
                }
                else
                {
                    return new BaseResultDto()
                    {
                        IsSuccess = false,
                        Code = HttpResultCode.Fail,
                        Message = "未查询到报名信息!"
                    };
                }
            }
            catch (Exception ex)
            {
                return new BaseResultDto()
                {
                    IsSuccess = false,
                    Code = HttpResultCode.Error,
                    Message = ex.Message
                };
            }
        }

        /// <summary>
        /// 下载excel表
        /// </summary>
        /// <returns></returns>
        public async Task<ResultDto<string>> ExportRegistrationInfoList(GetRegistrationInfoListQuery Query)
        {
            try
            {
                var res = await GetRegistrationInfoList(Query);
                if (res.Data == null)
                {
                    res.Data = new List<RegistrationInfoListDto>();
                }
                var path = ExportHelper.Export(res.Data.ToList(), "");
                return new ResultDto<string>()
                {
                    Data = path,
                    IsSuccess = true,
                    Code = (int)HttpResultCode.Success,
                    Message = "成功"
                };
            }
            catch (Exception ex)
            {
                return new ResultDto<string>()
                {
                    Data = "",
                    IsSuccess = false,
                    Code = (int)HttpResultCode.Error,
                    Message = ex.Message
                };
            }
        }

        /// <summary>
        /// 下载PDF表
        /// </summary>
        /// <returns></returns>
        public async Task<ResultDto<string>> PDFRegistrationInfoList(GetRegistrationInfoListQuery Query)
        {
            try
            {
                var res = await GetRegistrationInfoList(Query);
                if (res.Data == null)
                {
                    res.Data = new List<RegistrationInfoListDto>();
                }
                var path = PDFHelper.HtmlToPdf("<div>测试</div><br/><div>测试</div>", "测试水印", "BM");
                return new ResultDto<string>()
                {
                    Data = path,
                    IsSuccess = true,
                    Code = (int)HttpResultCode.Success,
                    Message = "成功"
                };
            }
            catch (Exception ex)
            {
                return new ResultDto<string>()
                {
                    Data = "",
                    IsSuccess = false,
                    Code = (int)HttpResultCode.Error,
                    Message = ex.Message
                };
            }
        }

        /// <summary>
        /// 根据用户ID查询列表
        /// </summary>
        /// <param name="Query"></param>
        /// <returns></returns>
        public async Task<PagePagingDto<RegistrationInfoByUserListDto>> RegistrationInfoByUserList(RegistrationInfoByUserListQuery Query)
        {
            PagePagingDto<RegistrationInfoByUserListDto> result = new PagePagingDto<RegistrationInfoByUserListDto>();
            try
            {
                var where = " where 1=1";
                string sql = string.Format("select * from (select " +
                    "rif.Id,rif.CompeteName,rif.CompeteTel,rif.CompeteIdNo,rif.SensorNumber,rif.CompeteTeamName," +
                    "c.[Name] as CompetitionName, cp.[Name] as CompetitionProjectName,cp.GameBeginTime as CompetitionStartTime,cp.GameEndTime as CompetitionEndTime," +
                    "cp.DetailsAddress as CompetitionAddress,rif.RegistrationSubmissionTime,EmployeeId as EmployeeName,EmployeeId as EmployeeTelephone," +
                    "c.Merchants as Merchant,rif.PaymentOrderId as PaymentOrderNo,rif.RegistrationSource,rif.RegistrationStatus,rif.ReviewComments," +
                    "rif.AuditTime,rif.ReviewedUserId as ReviewedUser " +
                    "from T_B_RegistrationInfo rif " +
                    "join T_B_Competition c on rif.CompetitionID = c.Id " +
                    "join T_B_CompetitionProject cp on rif.CompetitionProjectID = cp.Id) com" + where);
                var list = await _sqlExecuterRepository.QueryAsync<RegistrationInfoByUserListDto>(sql);
                if (list.Count() > 0)
                {
                    result.Data = list.Skip((Query.PageIndex - 1) * Query.PageSize).Take(Query.PageSize);
                    result.TotalCount = list.Count();
                    result.Code = HttpResultCode.Success;
                    result.IsSuccess = true;
                    result.Message = "查询成功！";
                    result.TotalPage = (int)Math.Round((list.Count() / Query.PageSize).ObjToDecimal(), MidpointRounding.ToPositiveInfinity);
                }
                else
                {
                    result.TotalCount = 0;
                    result.Code = HttpResultCode.Fail;
                    result.IsSuccess = false;
                    result.Data = null;
                    result.Message = "未查询到数据";
                    result.TotalPage = 0;
                }
            }
            catch (Exception ex)
            {
                result.TotalCount = 0;
                result.Code = HttpResultCode.Error;
                result.IsSuccess = false;
                result.Data = null;
                result.Message = ex.Message;
            }
            return result;
        }

        /// <summary>
        /// 根据用户ID查询详情
        /// </summary>
        /// <param name="Query"></param>
        /// <returns></returns>
        public async Task<ResultDto<RegistrationInfoByUserDetailsDto>> RegistrationInfoByUserDetails(RegistrationInfoByUserDetailsQuery Query)
        {
            ResultDto<RegistrationInfoByUserDetailsDto> result = new ResultDto<RegistrationInfoByUserDetailsDto>();
            try
            {
                string sql = string.Format("select * from (select " +
                        "rif.Id,rif.CompeteName,rif.CompeteTel,rif.CompeteIdNo,rif.SensorNumber,rif.CompeteTeamName," +
                        "c.[Name] as CompetitionName, cp.[Name] as CompetitionProjectName,cp.GameBeginTime as CompetitionStartTime,cp.GameEndTime as CompetitionEndTime," +
                        "cp.DetailsAddress as CompetitionAddress,rif.RegistrationSubmissionTime,EmployeeId as EmployeeName,EmployeeId as EmployeeTelephone," +
                        "c.Merchants as Merchant,rif.PaymentOrderId as PaymentOrderNo,rif.RegistrationSource,rif.RegistrationStatus,rif.ReviewComments," +
                        "rif.AuditTime,rif.ReviewedUserId as ReviewedUser " +
                        "from T_B_RegistrationInfo rif " +
                        "left join T_B_Competition c on rif.CompetitionID = c.Id " +
                        $"left join T_B_CompetitionProject cp on rif.CompetitionProjectID = cp.Id) com where com.Id ='{Query.Id}'");
                var fir = await _sqlExecuterRepository.QueryFirstAsync<RegistrationInfoByUserDetailsDto>(sql);
                result.Code = HttpResultCode.Success;
                result.IsSuccess = true;
                result.Data = fir;
                result.Message = "查询成功";
            }
            catch (Exception ex)
            {
                result.Code = HttpResultCode.Error;
                result.IsSuccess = false;
                result.Data = null;
                result.Message = ex.Message;
            }
            return result;
        }

        /// <summary>
        /// 断用户是否报名 true,已经报名，false没有报名
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public async Task<BaseResultDto> IsRegistrationOrNot(IsRegistrationOrNotQuery query)
        {
            BaseResultDto baseResultDto = new BaseResultDto();
            try
            {
                var reginfo = await _repository.GetAllListAsync(info => info.CompeteName.Equals(query.CompeteName) && info.CompeteIdNo.Equals(query.CompeteIdNo) && info.CompetitionProjectId == query.CompetitionProjectId && (info.RegistrationStatus == (int)RegistrationStatusEnum.待审核 || info.RegistrationStatus == (int)RegistrationStatusEnum.报名成功));
                if (reginfo != null && reginfo.Count > 0)
                {
                    baseResultDto.IsSuccess = true;
                    baseResultDto.Code = HttpResultCode.Success;
                    baseResultDto.Message = "已查到报名！";
                }
                else
                {
                    baseResultDto.IsSuccess = false;
                    baseResultDto.Code = HttpResultCode.NotData;
                    baseResultDto.Message = "未查到报名！";
                }
            }
            catch (Exception e)
            {
                baseResultDto.IsSuccess = false;
                baseResultDto.Code = HttpResultCode.Error;
                baseResultDto.Message = e.Message.ToString();
            }
            return baseResultDto;
        }

        /// <summary>
        /// 判断赛事项目参赛队名是否存在，true存在，false不存在
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public async Task<BaseResultDto> IsCompeteTeamOrNot(IsCompeteTeamOrNotQuery query)
        {
            BaseResultDto dto = new();
            try {
                var comteaminfo = await _comTeamRepository.FirstOrDefaultAsync(info => info.IsDeleted == false 
                && info.CompetitionProjectId == query.CompetitionProjectId && info.Name == query.CompeteTeamName);
                if (comteaminfo != null)
                {
                    dto.IsSuccess = true;
                    dto.Code = HttpResultCode.Success;
                    dto.Message = "已存在参赛队名！";
                }
                else {
                    dto.IsSuccess = false;
                    dto.Code = HttpResultCode.NotData;
                    dto.Message = "不存在参赛队名！";
                }
            } catch (Exception e) {
                dto.IsSuccess = false;
                dto.Code = HttpResultCode.Error;
                dto.Message = e.Message.ToString();
            }
            return dto;
        }

        /// <summary>
        /// 批量审批报名
        /// </summary>
        /// <param name="infos"></param>
        /// <returns></returns>
        public async Task<BaseResultDto> ApprovalRegistrationInfoList(ApprovalRegistrationInfos infos)
        {
            BaseResultDto resultDto = new BaseResultDto();
            try
            {
                var token = UldAdminSessionContext.GetCurrentUserInfo(_context);
                var currentNow = DateTime.Now;
                //先判断Token用户，免得退款之后在验证失败
                var userinfo = await _userInfoRepository.FirstOrDefaultAsync(info => info.Id == token.Id);
                if (userinfo == null)
                {
                    return new BaseResultDto()
                    {
                        IsSuccess = false,
                        Code = HttpResultCode.Fail,
                        Message = "ToKen传入UID有误！"
                    };
                }
                //查询报名信息未删除和报名状态为待审核的
                var regs = await _repository.GetAllListAsync(r => r.IsDeleted == false);

                //查询赛事项目未删除和
                var projects = await _comProjectRepository.GetAllListAsync(p => p.IsDeleted == false);

                //查询报名未删除的
                var rInfos = await _repository.GetAllListAsync(r => r.IsDeleted == false);

                //查询未删除的订单信息
                var orderInfos = await _payOrderRepository.GetAllListAsync(o => o.IsDeleted == false);

                foreach (var id in infos.Ids)
                {
                    var item = regs.FirstOrDefault(r => r.Id == id);
                    if (!item.IsNullAndEmpty())
                    {
                        #region 审核不通过则退款
                        //审核不通过则退款
                        if (infos.RegistrationStatus != 1)
                        {
                            //是否退钱
                            bool isrefund = true;
                            var projectinfo = projects.FirstOrDefault(p => p.Id == item.CompetitionProjectId);
                            if (projectinfo.IsNullAndEmpty())
                            {
                                resultDto = new BaseResultDto()
                                {
                                    IsSuccess = false,
                                    Code = HttpResultCode.Fail,
                                    Message = "审核项目不存在！"
                                };
                                return resultDto;
                            }
                            //2:个人赛
                            if (projectinfo.GameType != 2)
                            {
                                //如果是团体赛，全被审核失败，最后一个的时候才退款，否则不退款
                                var reginfolist = rInfos.Where(info => info.CompetitionId == item.CompetitionId &&
                                info.CompetitionProjectId == item.CompetitionProjectId
                                && info.CompeteTeamName == item.CompeteTeamName
                                && info.PaymentOrderId == item.PaymentOrderId).ToList();

                                if (!reginfolist.IsNullAndEmpty() || reginfolist.Count == 0)
                                {
                                    isrefund = false;
                                }
                                else
                                {
                                    isrefund = true;
                                    foreach (var reg in reginfolist)
                                    {
                                        //多条表示团体赛，判断除开自己是否还存在待审核和报名成功，有一个待审核或报名成功，就不退钱
                                        if (reg.Id != item.Id)
                                        {
                                            //1:待审核 2:报名成功
                                            if (reg.RegistrationStatus == 1 || reg.RegistrationStatus == 2)
                                            {
                                                isrefund = false;
                                                break;
                                            }
                                        }
                                    }
                                    //如果退钱则说明是最后一个不同过，则删除参赛团队信息，避免其他人不能复用该名称
                                    if (isrefund)
                                    {
                                        var comteaminfo = await _comTeamRepository.FirstOrDefaultAsync(info => info.Id == item.CompeteTeamId);
                                        if (comteaminfo != null)
                                        {
                                            comteaminfo.IsDeleted = true;
                                            await _comTeamRepository.UpdateAsync(comteaminfo);
                                        }
                                    }
                                }
                            }

                            if (isrefund)
                            {
                                //查询订单数据
                                var payorder = orderInfos.FirstOrDefault(info => info.Id == item.PaymentOrderId);
                                if (payorder != null && payorder.PaymentFee > 0)
                                {
                                    var str = projectinfo.Name + "报名审核未通过退款";
                                    //退款
                                    RefundQuery refundquery = new RefundQuery();
                                    refundquery.OutTradeNo = payorder.OrderNumber;
                                    refundquery.Amount = item.Money;
                                    refundquery.Reason = str;

                                    WeiXinTenPayV3Service weixinpay = new WeiXinTenPayV3Service(_context);
                                    var refundret = await weixinpay.Refund(refundquery);
                                    if (!refundret.IsSuccess)
                                    {
                                        resultDto = new BaseResultDto()
                                        {
                                            IsSuccess = false,
                                            Code = HttpResultCode.Fail,
                                            Message = "退款失败：" + refundret.Message
                                        };
                                        return resultDto;
                                    }
                                    //订单操作表数据录入 
                                    PaymentOrderOperationInfo operinfo = new PaymentOrderOperationInfo();
                                    operinfo.CreateTime = currentNow;
                                    operinfo.CreateUserId = userinfo.Id;
                                    operinfo.OperationName = userinfo.UserName;
                                    operinfo.OperationTime = currentNow;
                                    operinfo.OperationDetails = str;
                                    operinfo.PaymentOrderID = payorder.Id;
                                    operinfo.RegistrationID = item.Id;
                                    operinfo.OrderState = 3;
                                    operinfo.PaymentState = 3;
                                    await _oderoperRepository.InsertAsync(operinfo);

                                    //判断订单钱是否全部退完。退完更改状态
                                    decimal operfee = 0;
                                    operfee += item.Money;//加上当前退款金额是因为ABP过后才会插入表数据
                                    var orderoperlist = await _oderoperRepository.GetAllListAsync(info => info.PaymentOrderID == payorder.Id &&
                                    info.PaymentState == 3);
                                    if (orderoperlist != null && orderoperlist.Count > 0)
                                    {
                                        foreach (var orderoperitem in orderoperlist)
                                        {
                                            operfee += (await _repository.FirstOrDefaultAsync(info => info.Id == orderoperitem.RegistrationID)).Money;
                                        }
                                    }
                                    if (payorder.PaymentFee <= operfee)
                                    {
                                        payorder.PaymentStatus = 3;
                                        payorder.OrderStatus = 3;
                                        payorder.UpdateUserId = userinfo.Id;
                                        payorder.UpdateTime = currentNow;
                                        await _payOrderRepository.UpdateAsync(payorder);
                                    }
                                }
                                //订单金额为0 更改订单状态
                                if (payorder != null && payorder.PaymentFee == 0)
                                {
                                    payorder.PaymentStatus = 3;
                                    payorder.OrderStatus = 3;
                                    payorder.UpdateUserId = userinfo.Id;
                                    payorder.UpdateTime = currentNow;
                                    await _payOrderRepository.UpdateAsync(payorder);
                                }
                            }
                        }
                        #endregion

                        //更改报名状态
                        if (infos.RegistrationStatus != 1)
                        {
                            //报名失败
                            item.RegistrationStatus = 3;
                        }
                        else
                        {
                            //报名成功
                            item.RegistrationStatus = 2;
                        }
                        item.ReviewComments = infos.ReviewComments;
                        item.AuditTime = currentNow;
                        item.ReviewedUserId = userinfo.Id;
                        item.UpdateTime = currentNow;
                        item.UpdateUserId = userinfo.Id;
                        await _repository.UpdateAsync(item);
                        resultDto = new BaseResultDto()
                        {
                            IsSuccess = true,
                            Code = HttpResultCode.Success,
                            Message = "操作成功"
                        };
                    }
                    else
                    {
                        resultDto = new BaseResultDto()
                        {
                            IsSuccess = false,
                            Code = HttpResultCode.Fail,
                            Message = "未查询到报名信息!"
                        };
                        return resultDto;
                    }
                }

                return resultDto;
            }
            catch (Exception ex)
            {
                return new BaseResultDto()
                {
                    IsSuccess = false,
                    Code = HttpResultCode.Error,
                    Message = ex.Message
                };
            }
        }
    }
}
